﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using Microsoft.Xna.Framework;

namespace TopShooter
{
    public partial class Scene
    {
        public class State
        {
            public string CurrentSceneName;
            public List<Info> SceneContent;
            public string StaticContent;

            public State(Scene scene)
            {
                CurrentSceneName = scene.Name;
                SceneContent = scene.CaptureDynamicContent();

                StaticContent = scene.GetStaticContent();
            }

            private State()
            {
            }

            public void Save()
            {
                XmlSerializer ser = new XmlSerializer(typeof(State));
                System.IO.FileStream stream = new System.IO.FileStream(Manager.SceneFolder + CurrentSceneName + ".xml", System.IO.FileMode.Create);
                ser.Serialize(stream, this);

                stream.Close();
            }

            public static State Load(string name)
            {
                XmlSerializer ser = new XmlSerializer(typeof(State));
                System.IO.FileStream stream = new System.IO.FileStream(Manager.SceneFolder + name + ".xml", System.IO.FileMode.Open);

                State s = ser.Deserialize(stream) as State;

                stream.Close();

                return s;
            }

            public void Apply(Scene scene, bool replaceCurrentContent)
            {
					// Load the scene and ensure all of the lines are the same length.
                int width;
                List<string> lines = new List<string>();
					 SortedList<int, Portal.PortalTarget> portaldefs = new SortedList<int, Portal.PortalTarget>();

					 if (replaceCurrentContent)
					 {
						 DynamicContentRegistry.Remove(scene.Name);
						 DynamicContentRegistry.Add(scene.Name, SceneContent);
					 }
					 else
					 {	
						 if (!scene.HasDynamicContent)
							 DynamicContentRegistry.Add(scene.Name, SceneContent);
					 }

                using (StringReader reader = new StringReader(StaticContent))
                {
                    string line = reader.ReadLine();
                    width = line.Length;

                    while (line != null)
                    {
                        lines.Add(line);
                        if (line.Length != width)
                            throw new Exception(String.Format("The length of line {0} is different from all preceeding lines.", lines.Count));
                        line = reader.ReadLine();

                        if (line == "===")
                        {
                            break;
                        }
                    }
                    line = reader.ReadLine();

                    int startinPortalID = 0;

                    while (line != null)
                    {
                        int portalID = line[0] - '0';
                        Portal.PortalTarget pd = new Portal.PortalTarget(line.Substring(2));
                        portaldefs.Add(portalID, pd);
                        if (portalID == scene.SendingPortal.Portal)
                        {
                            scene.StartingPortal = pd;
                            startinPortalID = portalID;

                            if (pd.IsCheckPoint)
                            {
                                Game.Instance.CurrentCheckPoint = scene.SendingPortal;
                            }
                        }
                        line = reader.ReadLine();
                    }
                    if (scene.StartingPortal == null)
                    {
                        scene.StartingPortal = portaldefs[0];
                        scene.SendingPortal.Portal = startinPortalID;
                    }
                }
                // Allocate the tile grid.
                scene.TileDimension = new Point(width, lines.Count);
                scene.Size = new Point(width * Tile.Size.X, lines.Count * Tile.Size.Y);
                scene._tiles = new Tile[scene.TileDimension.X, scene.TileDimension.Y];

                for (int row = 0; row < scene.Height; ++row)
                {	// load the tiles now
                    for (int column = 0; column < scene.Width; ++column)
                    {
                        // to load each tile.
                        char tileType = lines[row][column];
                        if (scene._tiles[column, row] == null)
                        {
                            Tile t = scene.LoadTile(tileType, column, row, portaldefs);
                            if (t != null)
                            {
                                scene.SetTile(t, new Coordinate(column, row));
                                //_tiles[x, y] = t;
                                //t.LoadContent(this);
                                //       t.OnAdded(this, x, y);
                            }
                        }
                    }
                }
                if (scene.HasDynamicContent)
                {
                    List<Info> dc;
                    DynamicContentRegistry.TryGetValue(scene.Name, out dc);

                    foreach (Info info in dc)
                    {
                        info.Create(scene);
                    }
                }
                scene.TrimSize();
            }



        }
    }
}
